<?php
declare(strict_types=1);

namespace App\Controller;

use App\Controller\Admin\BaseController;
use App\Helper\RequestHelper;
use App\Model\ContentItem;
use App\Model\ContentMenu;
use Hyperf\HttpServer\Annotation\AutoController;
use Hyperf\ModelCache\Manager;
use Hyperf\Utils\ApplicationContext;
use Psr\Http\Message\ResponseInterface;
use Psr\SimpleCache\CacheInterface;

/**
 * @AutoController
 */
class IndexController extends AbstractController
{
    public function index(): ResponseInterface
    {
        return $this->response->redirect('/index.html');
    }

    public function menuOptions(): ResponseInterface
    {
        if (!RequestHelper::isAjax($this->request)) {
            return $this->response->redirect('/404.html');
        }
        $cacheKey = 'menu_select_options';
        $cache = ApplicationContext::getContainer()->get(CacheInterface::class);
        $value = $cache->get($cacheKey, null);
        if (is_null($value)) {
            $value = ContentMenu::getAllSelectOptions();
            $cache->set($cacheKey, $value, $value ? 3600 : 600);
        }
        return $this->response->json(BaseController::genSuccessData($value));
    }

    public function itemTypes(): ResponseInterface
    {
        if (!RequestHelper::isAjax($this->request)) {
            return $this->response->redirect('/404.html');
        }
        return $this->response->json(BaseController::genSuccessData(ContentItem::TYPE_NAMES));
    }

    public function itemList(): ResponseInterface
    {
        if (!RequestHelper::isAjax($this->request)) {
            return $this->response->redirect('/404.html');
        }

        $queryBuilder = ContentItem::query()
            ->select(['id'])
            ->where('status', '=', 4)
            ->where('main_id', '=', 0)
            ->whereNull('deleted_at');

        $menuId = $this->request->query('menu_id', '');
        $menuId = (strlen($menuId) ? intval($menuId) : -1);
        if ($menuId >= 0) {
            $queryBuilder->where('menu_id', '=', $menuId);
        }

        $typeId = $this->request->query('type_id', '');
        $typeId = (strlen($typeId) ? intval($typeId) : -1);
        if ($typeId >= 0) {
            $queryBuilder->where('type_id', '=', $typeId);
        }

        $title = trim($this->request->query('title', ''));
        if (!empty($title)) {
            $queryBuilder->where('title', 'like', '%' . $title . '%');
        }

        $count = ContentItem::getCountByBuilderFromCache($queryBuilder);

        $page = max(1, intval($this->request->query('page', 1)));
        $limit = intval($this->request->query('limit', 50));
        $queryBuilder->orderByDesc('top_number')
            ->orderByDesc('sort_number')
            ->orderByDesc('created_at')
            ->forPage($page, $limit);

        $data = ContentItem::findManyFromCache(ContentItem::getIdsByBuilderFromCache($queryBuilder));

        return $this->response->json(BaseController::genSuccessData($data, $count));
    }

    public function itemInfo(): ResponseInterface
    {
        if (!RequestHelper::isAjax($this->request)) {
            return $this->response->redirect('/404.html');
        }

        $id = $this->request->query('id', 0);
        $id = intval($id);
        if ($id <= 0) {
            return $this->response->json(BaseController::genErrorData());
        }

        $model = ContentItem::findFromCache($id); // var_dump($model);
        if (!$model || $model->main_id != 0 || $model->status != 4 || !empty($model->deleted_at)) {
            return $this->response->json(BaseController::genErrorData());
        }

        $page = max(1, intval($this->request->query('page', 1)));
        --$page;

        $queryBuilder = ContentItem::query()->select(['id'])->where('main_id', '=', $id)->orderBy('page_number');
        $models = ContentItem::findManyFromCache(ContentItem::getIdsByBuilderFromCache($queryBuilder));
        $models = $models->toArray();
        array_unshift($models, $model);
        $count = count($models);

        if ($model->type_id == 0) {
            $pageData = ($models[$page] ?? null);
        } else {
            $pageData = $models;
        }

        return $this->response->json(BaseController::genSuccessData(['main' => $model, 'page' => $pageData], $count));
    }

    public function addViewedCount(): ResponseInterface
    {
        if (!RequestHelper::isAjax($this->request)) {
            return $this->response->redirect('/404.html');
        }
        $id = $this->request->post('id', 0);
        $id = intval($id);
        if ($id <= 0) {
            return $this->response->json(BaseController::genErrorData());
        }
        ApplicationContext::getContainer()->get(Manager::class)->increment($id, 'viewed_count', 1, ContentItem::class);
        return $this->response->json(BaseController::genSuccessData());
    }

    public function addLikeCount(): ResponseInterface
    {
        if (!RequestHelper::isAjax($this->request)) {
            return $this->response->redirect('/404.html');
        }
        $id = $this->request->post('id', 0);
        $id = intval($id);
        if ($id <= 0) {
            return $this->response->json(BaseController::genErrorData());
        }
        $rateLimitId = RequestHelper::getClientIp($this->request) . '_' . $id;
        if (!RequestHelper::rateLimit($rateLimitId, 5, 86400)) {
            return $this->response->json(BaseController::genErrorData('每个IP对每篇文章,每24小时,最多赞5次!'));
        }
        ApplicationContext::getContainer()->get(Manager::class)->increment($id, 'liked_count', 1, ContentItem::class);
        return $this->response->json(BaseController::genSuccessData());
    }
}
